home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch11 / BSpline2.frm (.txt) < prev    next >
Visual Basic Form  |  1999-06-12  |  9KB  |  315 lines

  1. VERSION 5.00
  2. Begin VB.Form frmBspline2 
  3.    Caption         =   "BSpline2"
  4.    ClientHeight    =   5430
  5.    ClientLeft      =   2175
  6.    ClientTop       =   645
  7.    ClientWidth     =   4830
  8.    LinkTopic       =   "Form1"
  9.    PaletteMode     =   1  'UseZOrder
  10.    ScaleHeight     =   362
  11.    ScaleMode       =   3  'Pixel
  12.    ScaleWidth      =   322
  13.    Begin VB.CheckBox chkShowT 
  14.       Caption         =   "Show t Values"
  15.       Height          =   255
  16.       Left            =   1680
  17.       TabIndex        =   8
  18.       Top             =   300
  19.       Width           =   1755
  20.    End
  21.    Begin VB.TextBox txtK 
  22.       Height          =   285
  23.       Left            =   1140
  24.       TabIndex        =   6
  25.       Text            =   "3"
  26.       Top             =   45
  27.       Width           =   375
  28.    End
  29.    Begin VB.CommandButton cmdNew 
  30.       Caption         =   "New"
  31.       Enabled         =   0   'False
  32.       Height          =   375
  33.       Left            =   4320
  34.       TabIndex        =   5
  35.       Top             =   0
  36.       Width           =   495
  37.    End
  38.    Begin VB.CommandButton cmdGo 
  39.       Caption         =   "Go"
  40.       Default         =   -1  'True
  41.       Enabled         =   0   'False
  42.       Height          =   375
  43.       Left            =   3600
  44.       TabIndex        =   4
  45.       Top             =   0
  46.       Width           =   495
  47.    End
  48.    Begin VB.CheckBox chkControlPoints 
  49.       Caption         =   "Show Control Points"
  50.       Height          =   255
  51.       Left            =   1680
  52.       TabIndex        =   3
  53.       Top             =   0
  54.       Value           =   1  'Checked
  55.       Width           =   1755
  56.    End
  57.    Begin VB.TextBox txtDt 
  58.       Height          =   285
  59.       Left            =   240
  60.       TabIndex        =   2
  61.       Text            =   "0.05"
  62.       Top             =   45
  63.       Width           =   615
  64.    End
  65.    Begin VB.PictureBox picCanvas 
  66.       AutoRedraw      =   -1  'True
  67.       Height          =   4815
  68.       Left            =   0
  69.       ScaleHeight     =   317
  70.       ScaleMode       =   3  'Pixel
  71.       ScaleWidth      =   317
  72.       TabIndex        =   0
  73.       Top             =   600
  74.       Width           =   4815
  75.    End
  76.    Begin VB.Label Label1 
  77.       Caption         =   "K"
  78.       Height          =   255
  79.       Index           =   0
  80.       Left            =   960
  81.       TabIndex        =   7
  82.       Top             =   60
  83.       Width           =   255
  84.    End
  85.    Begin VB.Label Label1 
  86.       Caption         =   "dt"
  87.       Height          =   255
  88.       Index           =   1
  89.       Left            =   0
  90.       TabIndex        =   1
  91.       Top             =   60
  92.       Width           =   255
  93.    End
  94. Attribute VB_Name = "frmBspline2"
  95. Attribute VB_GlobalNameSpace = False
  96. Attribute VB_Creatable = False
  97. Attribute VB_PredeclaredId = True
  98. Attribute VB_Exposed = False
  99. Option Explicit
  100. Private Const GAP = 2
  101. ' The endpoints are points 1 and 4. The control
  102. ' points are points 2 and 3.
  103. Private MaxPt As Integer
  104. Private PtX() As Single
  105. Private PtY() As Single
  106. Private MakingNew As Boolean
  107. ' The index of the point being dragged.
  108. Private Dragging As Integer
  109. ' Kvalue determines the smoothness of the curve.
  110. Private Kvalue As Integer
  111. ' t runs between 0 and MaxPt - Kvalue + 2.
  112. Private MaxT As Single
  113. ' Recursively compute the blending function.
  114. Private Function Blend(ByVal i As Integer, ByVal k As Integer, ByVal t As Single) As Single
  115. Dim numer As Single
  116. Dim denom As Single
  117. Dim value1 As Single
  118. Dim value2 As Single
  119. Dim newt As Single
  120.     If i > 0 Then
  121.         newt = t - i + MaxPt + 1
  122.         Do While newt >= MaxPt + 1
  123.             newt = newt - (MaxPt + 1)
  124.         Loop
  125.         Do While newt < 0
  126.             newt = newt + (MaxPt + 1)
  127.         Loop
  128.         Blend = Blend(0, k, newt)
  129.         Exit Function
  130.     End If
  131.     ' Base case for the recursion.
  132.     If k = 1 Then
  133.         If (Knot(i) <= t) And (t < Knot(i + 1)) Then
  134.             Blend = 1
  135.         ElseIf (t = MaxT) And (Knot(i) <= t) And (t <= Knot(i + 1)) Then
  136.             Blend = 1
  137.         Else
  138.             Blend = 0
  139.         End If
  140.         Exit Function
  141.     End If
  142.     denom = Knot(i + k - 1) - Knot(i)
  143.     If denom = 0 Then
  144.         value1 = 0
  145.     Else
  146.         numer = (t - Knot(i)) * Blend(i, k - 1, t)
  147.         value1 = numer / denom
  148.     End If
  149.     denom = Knot(i + k) - Knot(i + 1)
  150.     If denom = 0 Then
  151.         value2 = 0
  152.     Else
  153.         numer = (Knot(i + k) - t) * Blend(i + 1, k - 1, t)
  154.         value2 = numer / denom
  155.     End If
  156.     Blend = value1 + value2
  157. End Function
  158. ' Draw the curve on the indicated picture box.
  159. Private Sub DrawCurve(pic As PictureBox, start_t As Single, stop_t As Single, dt As Single)
  160. Dim t As Single
  161.     pic.Cls
  162.     pic.CurrentX = X(start_t)
  163.     pic.CurrentY = Y(start_t)
  164.     t = start_t + dt
  165.     Do While t < stop_t
  166.         pic.Line -(X(t), Y(t))
  167.         t = t + dt
  168.     Loop
  169.     pic.Line -(X(stop_t), Y(stop_t))
  170. End Sub
  171. ' Return the ith knot value.
  172. Private Function Knot(ByVal i As Integer) As Integer
  173.     Knot = i
  174. End Function
  175. ' The parametric function Y(t).
  176. Private Function Y(ByVal t As Single) As Single
  177. Dim i As Integer
  178. Dim value As Single
  179.     For i = 0 To MaxPt
  180.         value = value + PtY(i) * Blend(i, Kvalue, t)
  181.     Next i
  182.     Y = value
  183. End Function
  184. ' The parametric function X(t).
  185. Private Function X(ByVal t As Single) As Single
  186. Dim i As Integer
  187. Dim value As Single
  188.     For i = 0 To MaxPt
  189.         value = value + PtX(i) * Blend(i, Kvalue, t)
  190.     Next i
  191.     X = value
  192. End Function
  193. ' Use DrawCurve to draw the Bezier curve.
  194. Private Sub DrawBspline()
  195. Dim dt As Single
  196. Dim i As Integer
  197. Dim oldstyle As Integer
  198.     If MaxPt < 0 Then Exit Sub
  199.     MousePointer = vbHourglass
  200.     Kvalue = CInt(txtK.Text)
  201.     dt = CSng(txtDt.Text)
  202.     MaxT = MaxPt + 1
  203.     DrawCurve picCanvas, 0, MaxT, dt
  204.     If chkControlPoints.value = vbChecked Then
  205.         ' Draw the control points.
  206.         For i = 0 To MaxPt
  207.             picCanvas.Line _
  208.                 (PtX(i) - GAP, PtY(i) - GAP)- _
  209.                 Step(2 * GAP, 2 * GAP), , BF
  210.         Next i
  211.         ' Connect the control points.
  212.         oldstyle = picCanvas.DrawStyle
  213.         picCanvas.DrawStyle = vbDot
  214.         picCanvas.CurrentX = PtX(MaxPt)
  215.         picCanvas.CurrentY = PtY(MaxPt)
  216.         For i = 0 To MaxPt
  217.             picCanvas.Line -(PtX(i), PtY(i))
  218.         Next i
  219.         picCanvas.DrawStyle = oldstyle
  220.     End If
  221.     ' Mark the t values if desired.
  222.     If chkShowT.value = vbChecked Then
  223.         For dt = 0 To MaxT Step 1#
  224.             picCanvas.Line (X(dt), Y(dt) - 5)-Step(0, 10)
  225.             picCanvas.Line (X(dt) - 5, Y(dt))-Step(10, 0)
  226.         Next dt
  227.     End If
  228.     MousePointer = vbDefault
  229. End Sub
  230. ' Either collect a new point or select a point and
  231. ' start dragging it.
  232. Private Sub picCanvas_MouseDown(button As Integer, Shift As Integer, X As Single, Y As Single)
  233. Dim i As Integer
  234.     ' If we are selecting points, do so now.
  235.     If MakingNew Then
  236.         MaxPt = MaxPt + 1
  237.         ReDim Preserve PtX(0 To MaxPt)
  238.         ReDim Preserve PtY(0 To MaxPt)
  239.         PtX(MaxPt) = X
  240.         PtY(MaxPt) = Y
  241.         picCanvas.Line _
  242.             (X - GAP, Y - GAP)- _
  243.             Step(2 * GAP, 2 * GAP), , BF
  244.         
  245.         If MaxPt >= 2 Then cmdGo.Enabled = True
  246.         
  247.         Exit Sub
  248.     End If
  249.     ' Otherwise start dragging a point.
  250.     ' Find a close point.
  251.     For i = 0 To MaxPt
  252.         If Abs(PtX(i) - X) <= GAP And _
  253.            Abs(PtY(i) - Y) <= GAP Then Exit For
  254.     Next i
  255.     If i > MaxPt Then Exit Sub
  256.     Dragging = i
  257.     picCanvas.DrawMode = vbInvert
  258.     PtX(Dragging) = X
  259.     PtY(Dragging) = Y
  260.     picCanvas.Line _
  261.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  262.         Step(2 * GAP, 2 * GAP), , BF
  263. End Sub
  264. ' Continue dragging a point.
  265. Private Sub picCanvas_MouseMove(button As Integer, Shift As Integer, X As Single, Y As Single)
  266.     If Dragging < 0 Then Exit Sub
  267.     picCanvas.Line _
  268.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  269.         Step(2 * GAP, 2 * GAP), , BF
  270.     PtX(Dragging) = X
  271.     PtY(Dragging) = Y
  272.     picCanvas.Line _
  273.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  274.         Step(2 * GAP, 2 * GAP), , BF
  275. End Sub
  276. ' Finish the drag and redraw the curve.
  277. Private Sub picCanvas_MouseUp(button As Integer, Shift As Integer, X As Single, Y As Single)
  278.     If Dragging < 0 Then Exit Sub
  279.     picCanvas.DrawMode = vbCopyPen
  280.     PtX(Dragging) = X
  281.     PtY(Dragging) = Y
  282.     Dragging = -1
  283.     DrawBspline
  284. End Sub
  285. Private Sub CmdGo_Click()
  286.     MakingNew = False
  287.     cmdNew.Enabled = True
  288.     DrawBspline
  289. End Sub
  290. ' Prepare to get new points.
  291. Private Sub CmdNew_Click()
  292.     MaxPt = -1
  293.     cmdGo.Enabled = False
  294.     cmdNew.Enabled = False
  295.     MakingNew = True
  296.     picCanvas.Cls
  297. End Sub
  298. Private Sub chkControlPoints_Click()
  299.     DrawBspline
  300. End Sub
  301. Private Sub Form_Load()
  302.     MakingNew = True
  303.     MaxPt = -1
  304.     Dragging = -1
  305. End Sub
  306. ' Make the picCanvas as big as possible.
  307. Private Sub Form_Resize()
  308.     picCanvas.Move 0, picCanvas.Top, _
  309.         ScaleWidth, ScaleHeight - picCanvas.Top
  310.     DrawBspline
  311. End Sub
  312. Private Sub chkShowT_Click()
  313.     DrawBspline
  314. End Sub
  315.